﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using DevExpress.XtraEditors;
using MDK.Model.Models;
using MDK.Common;
using MDK.Device;
using Newtonsoft.Json;
using MDK.Device.Devices;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using DevExpress.Services;
using MDK.Common.Helper;
using MDK.Device.Components;
using System.Windows.Threading;

namespace MDK.Winform
{
    public partial class ucPreControl : XtraUserControl
    {
        /// <summary>
        /// 样本数量监控定时器
        /// </summary>
        DispatcherTimer timer = new DispatcherTimer();
        public ucPreControl()
        {
            InitializeComponent();
            InitEvent();

            timer.Tick += new EventHandler(UpdateQuantity);
            timer.Interval = TimeSpan.FromSeconds(2);   //设置刷新的间隔时间
            timer.Start();
            ControlState();
        }

        private void UpdateQuantity(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(arg =>
            {
                lblCut.Text = InitTubeCount(TubeTypes.Meimian).ToString();
            });
        }

        private int InitTubeCount(TubeTypes TubeType)
        {
            return App.flow.PosModel.FreezerPositions.SelectMany(t => t.SelectMany(s => s.Tubes)).Count(t => t.Type == TubeType);
        }

        private void InitEvent()
        {
            EventHelper.Add("HandoverStateChanged", HandoverStateChanged);
            EventHelper.Add("InputBarcode", InputBarcodeChanged);
            EventHelper.Add("DeviceScrammed", DeviceScrammed);
            EventHelper.Add("EndHandover", EndHandover);
        }

        private void EndHandover(object sender, EventArgs e)
        {
            bool isClose = false;
            string url = WebApiProxyHelper.StructureUrl(App.systemSetting["ATMWebApiProxyAddress"], App.systemSetting["ATMWebApiProxyPort"], "ATMMessage/EndHandover");
            WebApiProxyHelper.PostAndReturn<bool>(url, ref isClose);
        }

        private void DeviceScrammed(object sender, EventArgs e)
        {
            var args = sender as Dictionary<string, object>;
            var device = args["device"] as Pallet;
            frmEmergencystop frm = new frmEmergencystop();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                args.Add("continue",true);
            }
            else
            {
                args.Add("continue", false);
            }
        }

        private void InputBarcodeChanged(object sender, EventArgs e)
        {
            var args = sender as Dictionary<string, object>;
            var arg = args["pallet"] as Pallet;

            SpeechHelper.SpeekAynsc("有无条码试管,请先补条码，不然程序无法执行");
            int _position = App.flow.PosModel.DesktopPositions.FindIndex(t => t.Pallet == arg);

            frmOperationNoCodeTube frm = new frmOperationNoCodeTube(_position);
            frm.ShowDialog();
        }

        #region 发送给ATM
        /// <summary>
        /// 交接单状态改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandoverStateChanged(object sender, EventArgs e)
        {
            var args = sender as Dictionary<string, object>;
            var arg = args["arg"] as HandoverStateChangedArgs;
            if (arg.Code >= 0 && (int)arg.Code < 100)
            {
                string url = WebApiProxyHelper.StructureUrl(App.systemSetting["ATMWebApiProxyAddress"], App.systemSetting["ATMWebApiProxyPort"], "ATMMessage/HandoverStateChanged");
                WebApiProxyHelper.PostAndReturn<HandoverStateChangedArgs>(url, ref arg);
                args["arg"] = arg;
            }
            else if ((int)arg.Code >= 100)
            {
                if (arg.Code == FlowMesssages.FrontBalanceFailed || arg.Code == FlowMesssages.EmptyPalletUseUp
                    || arg.Code == FlowMesssages.FrontPositionUseUp)
                {
                    SpeechHelper.SpeekAynsc(arg.Message);
                    frmDeskOperation frm = new frmDeskOperation(arg.Message);
                    frm.ShowDialog();
                }
            }
        }
        #endregion


        /// <summary>
        /// 温度
        /// </summary>
        private void GetFreezerTemperatures()
        {
            while (true)
            {
                Thread.Sleep(1000 * 60);
                T_Temperatures info = new T_Temperatures();
                try
                {
                    info.Id = Guid.NewGuid().ToString("N");
                    info.Time = DateTime.Now;
                    var temperatures = App.flow.SysModel.Freezer?.FreezerController.GetTemperatures();
                    if (temperatures == null)
                    {
                        info.Temperature1 = "未知";
                        info.Temperature2 = "未知";
                    }
                    else
                    {
                        if (temperatures.Count() == 2)
                        {
                            info.Temperature1 = temperatures[0].ToString();
                            info.Temperature2 = temperatures[1].ToString();
                        }
                    }
                }
                catch
                {
                    info.Temperature1 = "未知";
                    info.Temperature2 = "未知";
                }
                WebAPIHelper.Post<T_Temperatures>("Temperatures/Add", info);
            }
        }

        private void ucPreControl_Load(object sender, EventArgs e)
        {
            ThreadPool.QueueUserWorkItem(arg =>
            {
                GetFreezerTemperatures();
            });
        }

        private void btnBlack_Click(object sender, EventArgs e)
        {
            if (!IsNewTasks())
            {
                return;
            }

            FastMessageBox.Warnning("请确认载条上的试管已全部清空");
            if (IsContinue(App.flow.SysModel.Back.AusbioSersors, 32))
            {
                //构造task
                T_Task info = new T_Task()
                {
                    Id = Guid.NewGuid().ToString("N"),
                    StripType = 0,
                    DealPerson = "Admin",
                    DealTime = DateTime.Now,
                    DealCount = (int)spCount.Value,
                    DealType = 1,
                    State = "开始处理"
                };
                if (WebAPIHelper.Post<T_Task>("Task/Add", info))
                    App.flow.BeginTransferToAusbio(info.Id, 1, info.DealCount.Value);
            }
        }

        private void btnDeal_Click(object sender, EventArgs e)
        {
            if (!IsNewTasks())
            {
                return;
            }

            FastMessageBox.Warnning("请确认载条上的试管已全部清空");
            if (IsContinue(App.flow.SysModel.Back.TecanSersors, 16))
            {
                //构造task
                T_Task info = new T_Task()
                {
                    Id = Guid.NewGuid().ToString("N"),
                    StripType = 2,
                    DealPerson ="admin",
                    DealTime = DateTime.Now,
                    DealCount = (int)spCount.Value,
                    DealType = 2,
                    State = "开始处理"
                };
                if (WebAPIHelper.Post<T_Task>("Task/Add", info))
                    App.flow.BeginTransferToTecen(info.Id, 1, info.DealCount.Value);
            }
        }
        
        //private void btnYP_Click(object sender, EventArgs e)
        //{
        //    if (IsContinue(App.flow.SysModel.Back.BackManSersors, 10))
        //    {
        //        //构造task
        //        T_Task info = new T_Task()
        //        {
        //            Id = Guid.NewGuid().ToString("N"),
        //            StripType = 3,
        //            DealPerson = App.currentUser.RealName,
        //            DealTime = DateTime.Now,
        //            DealCount = (int)spCount.Value,
        //            DealType = 3,
        //            State = "开始处理"
        //        };
        //        if (WebAPIHelper.Post<T_Task>("Task/Add", info))
        //            App.flow.BeginTransferToBackman(info.Id, 1, info.DealCount.Value);
        //    }
        //}

        /// <summary>
        /// 判断是否可以继续
        /// </summary>
        /// <param name="sensors"></param>
        /// <param name="stripindexCount"></param>
        /// <returns></returns>

        public bool IsContinue(ISensor[] sensors,int stripindexCount)
        {
            var maxCount = InitTubeCount(TubeTypes.Meimian);
            if (maxCount < spCount.Value)
            {
                if (FastMessageBox.Question("只有" + maxCount + "根试管,请确认是否全部推出") == DialogResult.OK)
                {
                    spCount.Value = maxCount;
                }
                else
                {
                    return false;
                }
            }
            if (isSupplyPallet(spCount.Value))
            {
                string Message = "请先补一个空托，不然程序无法执行";
                SpeechHelper.SpeekAynsc(Message);
                if (FastMessageBox.Warnning(Message) == DialogResult.OK)
                {
                    frmDeskOperation frm = new frmDeskOperation(Message);
                    frm.ShowDialog();
                }
                else
                {
                    return false;
                }
            }
            return IsStripOk(sensors,stripindexCount);
        }
        /// <summary>
        ///  //判断载条是否够用
        /// </summary>
        /// <param name="sensors"></param>
        /// <param name="stripindexCount"></param>
        /// <returns></returns>
        public bool IsStripOk(ISensor[] sensors, int stripindexCount,int HandleCut=0)
        {
            var stripcount = Math.Ceiling((HandleCut == 0 ? spCount.Value : HandleCut) / stripindexCount);
            if (sensors.Count(t => t.IsActive()) < stripcount)
            {
                FastMessageBox.Show("载条数量不够");
                return false;
            }
            return true;
        }
        /// <summary>
        /// 是否补托
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        private bool isSupplyPallet(decimal count)
        {
            int sum = 0;
            var pallets = App.flow.PosModel.FreezerPositions.SelectMany(t => t).Where(t => t.Type == TubeTypes.Meimian).OrderBy(t => t.MinGatherTime).ToArray();
            foreach (var pallet in pallets)
            {
                sum += pallet.TubeCount;
                if (sum == count)
                    return false;
                if (sum > count)
                {
                    if (!App.flow.PosModel.DesktopPositions.Any(t => t.Pallet != null && t.Pallet.Type == TubeTypes.None))
                    {
                        return true;
                    }
                    return false;
                }
            }
            return true;
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (FastMessageBox.Warnning("清空后无法恢复，是否继续") == DialogResult.OK)
            {
                var samples = IDatatoFlow.GetSamples();
                var exceptFreezer = samples.Where(t => t.PostionType == "1");
                foreach (var sample in exceptFreezer)
                {
                    sample.Is_Delete = true;
                    IDatatoFlow.SampleDelete(sample);
                }
                App.flow.PosModel.FreezerPositions = Enumerable.Range(0, 6).Select(t => new Stack<Pallet>()).ToArray();
                FastMessageBox.Show("清空成功");
            }
            
        }

        DateTime _TimingTime;
        DispatcherTimer _timer = new DispatcherTimer();
        PalletStatus _PalletType;
        private void btnTimer_Click(object sender, EventArgs e)
        {
            if (!IsNewTasks())
            {
                return;
            }

            frmSetTime frm = new frmSetTime();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                if (frm.PalletType == PalletStatus.WaitToAusbio)
                {
                    if (!IsStripOk(App.flow.SysModel.Back.AusbioSersors, 32, 88))
                        return;
                }
                else
                {
                    if (!IsStripOk(App.flow.SysModel.Back.TecanSersors, 16, 88))
                        return;
                }
               
                _TimingTime = frm._TimingTime;
                _PalletType = frm.PalletType;
                _timer = new DispatcherTimer();

                lblPointOut.Text = $"开盖启动时间：{_TimingTime.ToString("yyyy/MM/dd HH:mm:ss")},转架类型为{(_PalletType== PalletStatus.WaitToAusbio?"奥斯邦":"帝肯")}";
                ControlState(true);
                _timer.Tick += new EventHandler(FiringEven);
                _timer.Interval = TimeSpan.FromSeconds(60);   //设置刷新的间隔时间
                _timer.Start();
                _IsTimingStart = true;
            }
        }
        bool _IsTimingStart=false;
        private void FiringEven(object sender, EventArgs e)
        {
            if (DateTime.Now <= _TimingTime)
            {
                return;
            }
            _timer.Stop();
            ControlState();
            _IsTimingStart = false;

            if (_PalletType == PalletStatus.WaitToAusbio)
            {
                T_Task info = new T_Task()
                {
                    Id = Guid.NewGuid().ToString("N"),
                    StripType = 0,
                    DealPerson = "Admin",
                    DealTime = DateTime.Now,
                    DealCount = InitTubeCount(TubeTypes.Meimian) >= 88 ? 88 : InitTubeCount(TubeTypes.Meimian),
                    DealType = 1,
                    State = "开始处理"
                };
                if (WebAPIHelper.Post<T_Task>("Task/Add", info))
                    App.flow.BeginTransferToAusbio(info.Id, 1, info.DealCount.Value);
            }
            else
            {
                //构造task
                T_Task info = new T_Task()
                {
                    Id = Guid.NewGuid().ToString("N"),
                    StripType = 2,
                    DealPerson = "admin",
                    DealTime = DateTime.Now,
                    DealCount = InitTubeCount(TubeTypes.Meimian) >= 88 ? 88 : InitTubeCount(TubeTypes.Meimian),
                    DealType = 2,
                    State = "开始处理"
                };
                if (WebAPIHelper.Post<T_Task>("Task/Add", info))
                    App.flow.BeginTransferToTecen(info.Id, 1, info.DealCount.Value);
            }

        }
        public void ControlState(bool IsHide=false)
        {
            lblPointOut.Visible = IsHide;
            btnDeleteTime.Visible = IsHide;
        }

        private void btnDeleteTime_Click(object sender, EventArgs e)
        {
            _timer.Stop();
             ControlState();
            _IsTimingStart = false;
             FastMessageBox.Warnning("取消任务成功");
        }
        bool IsNewTasks()
        {
            if (_IsTimingStart)
            {
                FastMessageBox.Warnning("定时任务已启动,请先取消在操作");
                return false;
            }
            if (!App.flow._IsTaskOk)
            {
                FastMessageBox.Warnning("当前任务未完成,无法开启新任务");
                return false;
            }
            return true;
        }
    }
}
